/* 
 * File:   main.cpp
 * Author: Chen Liu     Student Number:3996591
 *
 * Created on August 27, 2012, 2:26 PM
 */
/*                              Report
 * test1   Size: 100         Seed: 20          Max: 20            N: 20
 * In this situation, the Best_Fit scheme allocated the most bytes(172), while 
 * the  NextFit allocated the less bytes(152). As the size and Max is not very 
 * big, the efficiency is almost the same, just around 2 compares/block and 
 * 0 compares/byte.
 * 
 * test2   Size: 1000        Seed: 200         Max: 200           N: 20      
 * In this situation, the NextFit scheme allocated the most bytes(2324), which 
 * is more than twice with the WorstFit(1140). The efficiency of the four scheme
 * is almost the same, there is not apparent difference (0 compare/byte and 
 * 3~4 compares/bolck).
 * 
 * test3   Size: 100000      Seed: 200         Max: 200           N: 20
 * In this test case, the BestFit allocated the most bytes(192184), FirstFit and
 * WorstFit are almost the same, is around 185000. The lowest is NextFit, with
 * the number of 157760. But the NextFit is the fastest, with the data of 
 * 0 compares/byte and 2 compares/block, while the other three scheme is about 
 * 3 compares/byte and above 50 compares/block.
 * 
 * test4   Size: 100000      Seed: 2000         Max: 20000         N: 20
 * In this situation, only the max increase. As a result, there is slight change
 * with the total bytes allocated of four schemes. But the compares times decrease
 * rapidly except the NextFit, which was almost the same with test 3. 
 * 
 * From the four test cases, the performance will change when the average size 
 * of the memory blocks changed. In the same setting, the bigger average size of
 * memory blocks, the less compares/block and compares/byte.
 */
#include <cstdlib>
#include <iostream>
#include <iomanip>
#include <vector>
#include "dmm.h"

using namespace std;

void run(int size, int seed, int max, int N, Policy type){
    WORD *buff1 = new WORD[size];
    DMM dmm(buff1, size, type);
    
    vector<char*> listitem;
    int sd;
    sd = seed;
    for(int i=0;i<N;i++){
        
        srand(sd++);
        while(1){
            int numchars = (rand()%max+1)*4;
            char *p = dmm.New(numchars);
            if(p == 0){
                break;// memory full              
            }
            listitem.push_back(p);
        }
        srand(sd++);

        int m = listitem.size()/2;
        for(int j=0; j<m; j++){
            int pos = rand() % listitem.size();
            dmm.Delete(listitem.at(pos));
            char *d = listitem.at(pos);         
            listitem.erase(listitem.begin()+pos);
        }       
    }
    
    int bAlloc, blAlloc, Cmps;
    dmm.GetStats(bAlloc, blAlloc, Cmps);

    cout<<bAlloc<<setw(18)<<Cmps/bAlloc<<setw(21)<<blAlloc<<setw(18)<<Cmps/blAlloc<<endl;   
}

int main(int argc, char** argv) {

    int size, seed, max, N;
    //due with the para

    //cout << "Please input Size, Seed, Max and N in order:" << endl;
    if(argc==5){
        size = atoi(argv[1]);
        seed = atoi(argv[2]);
        max = atoi(argv[3]);
        N = atoi(argv[4]); 
    }
    else {
        cout << "Wrong parametric, please check" << endl;
        exit(0);
    }
        

    
    
    //debug
    /*
    size = 100;
    seed = 10;
    max = 10;
    N = 20;
    */
    cout<<setw(0)<<"Size: "<<size<<setw(15)<<"Seed: "<<seed<<setw(15)<<"Max: "<<max<<setw(15)<<"N: "<<N<<endl;
    cout<<endl;
    cout<<setw(10)<<" "<<setw(15)<<"Tot Bytes"<<setw(20)<<"Ave Cmps Per "<<setw(20)<<" Tot Blocks"<<setw(20)<<"Ave Cmps Per  "<<endl;
    cout<<setw(10)<<" "<<setw(15)<<"Allocated"<<setw(20)<<"Byte Allocated"<<setw(20)<<"Allocated "<<setw(20)<<" Block Allocated"<<endl;
    
    cout<<"FirstFit:"<<setw(13);
    run(size, seed, max, N, eFirstFit);
    
    cout<<"NextFit: "<<setw(13);
    run(size, seed, max, N, eNextFit);
    
    cout<<"Best_Fit:"<<setw(13);
    run(size, seed, max, N, eBestFit);
    
    cout<<"WorstFit:"<<setw(13);
    run(size, seed, max, N, eWorstFit);
    
}

